package sadmin

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/astaxie/beego/orm"
	"github.com/phinexdaz/ipapk"
	"github.com/satori/go.uuid"
	"image/png"
	"io/ioutil"
	"math"
	"net/http"
	"os"
	"os/exec"
	"shop/models/common"
	"strings"
	"time"
)

type App struct {
	Id int
	Name string
	Types string
	Company string
	Root string
	Describe string
	Picture string
	Version string
	Newfeatures string
	Icon string
	Status string
	Priority int
	Url string
	Download string
}

type Apk struct {
	Name     string
	BundleId string
	Version  string
	Build    string
//	Icon     image.Image
}
const status1="已上线"
const status2="待发布"
const status3="已下架"
const apitoken="997f075057f62e84135a455895f5e9e8"
func init()  {
	orm.RegisterModel(new(App))
}

func AppEveryPage(num int)float64  {
	if num<1{
		num=1
	}
	pageCount := math.Ceil((float64(getAppNum()) / float64(num)))
	return pageCount
}
type St struct {
	Ssub int64
	Sap []App
}
func AppPaging(num int,page int,by string,typ string,sta string) (St,error) {

	//通过账户获取其公司名

	//通过公司查看可见企业，
	//bywhat:=""
	//if common.StrDelTrim(by)!=""{
	//	bywhat="-priority"
	//}else {
	//	bywhat="id"
	//}

	var ap []App
	o := orm.NewOrm()
	var sub int64
	if common.StrDelTrim(typ) != "" {
		if common.StrDelTrim(sta) == "" {
			sub, _ = o.Raw("select * from app where status = ? and types = ? and (binary root like ?) ", status1,typ, "%,All,%").QueryRows(&ap)
			if common.StrDelTrim(by) != "" {
				_, _ = o.Raw("select * from app where status = ? and types = ? and (binary root like ?)  order by priority desc limit ?,?", status1,typ, "%,All,%", (page-1)*num, num).QueryRows(&ap)
			} else {
				_, _ = o.Raw("select * from app where status = ? and types = ? and (binary root like ?)  limit ?,?", status1,typ, "%,All,%", (page-1)*num, num).QueryRows(&ap)
			}
		} else {
			sub, _ = o.Raw("select * from app where status = ? and types = ? and (binary root like ? or binary root like ?) ", status1,typ, "%,All,%", "%,"+sta+",%").QueryRows(&ap)

			if common.StrDelTrim(by) != "" {
				_, _ = o.Raw("select * from app where status = ? and types = ? and (binary root like ? or binary root like ?)  order by priority desc limit ?,?", status1, typ,"%,All,%", "%,"+sta+",%", (page-1)*num, num).QueryRows(&ap)
			} else {
				_, _ = o.Raw("select * from app where status = ? and types = ? and (binary root like ? or binary root like ?) limit ?,?", status1,typ, "%,All,%", "%,"+sta+",%", (page-1)*num, num).QueryRows(&ap)
			}
		}
	} else {
	if common.StrDelTrim(sta) == "" {
		sub, _ = o.Raw("select * from app where status = ? and (binary root like ?) ", status1, "%,All,%").QueryRows(&ap)
		if common.StrDelTrim(by) != "" {
			_, _ = o.Raw("select * from app where status = ? and (binary root like ?)  order by priority desc limit ?,?", status1, "%,All,%", (page-1)*num, num).QueryRows(&ap)
		} else {
			_, _ = o.Raw("select * from app where status = ? and (binary root like ?)  limit ?,?", status1, "%,All,%", (page-1)*num, num).QueryRows(&ap)
		}
	} else {
		sub, _ = o.Raw("select * from app where status = ? and (binary root like ? or binary root like ?) ", status1, "%,All,%", "%,"+sta+",%").QueryRows(&ap)

		if common.StrDelTrim(by) != "" {
			_, _ = o.Raw("select * from app where status = ? and (binary root like ? or binary root like ?)  order by priority desc limit ?,?", status1, "%,All,%", "%,"+sta+",%", (page-1)*num, num).QueryRows(&ap)
		} else {
			_, _ = o.Raw("select * from app where status = ? and (binary root like ? or binary root like ?) limit ?,?", status1, "%,All,%", "%,"+sta+",%", (page-1)*num, num).QueryRows(&ap)
		}
	}
}
	var s St
	s.Sap=ap
	s.Ssub=sub
	return s,nil
	//com := new(App)
	//qs := o.QueryTable(com)
	////count,_:=qs.Count()
	//if num<1{num=1}
	//everyPageNum:=num
	////	总页数
	////pageCount := math.Ceil((float64(count) / float64(everyPageNum)))
	////	获取当前页码
	//if page==0{
	//	page=1
	//}
	//articles := new([]App)
	////获取上架的app
	//qs=qs.Filter("status",status1)
	////qs=qs.Filter("root__contains",account)
	////qs=qs.Filter("root","all")
	////获取对当前账号可见的app
	////rootapp:=new([]App)
	////for _,value:=range *articles{
	////	if value.Root=="all"{
	//	//		*rootapp=append(*rootapp,value)
	//	//	}
	//	//}
	//	//获取分页数据
	//	qs.Limit(everyPageNum, everyPageNum*(page - 1)).OrderBy(bywhat).All(articles)
	//	return *articles,nil
}

func AppCreate(url string) error  {
	apk, err := ipapk.NewAppParser(url)
	if err!=nil{
		return err
	}
	//if checkVersion(apk.Version,apk.Name)==false{
	//	return errors.New("version false")
	//}
	var ap App
	ap.Url=url
	ap.Name=apk.Name
	ap.Version=apk.Version
	o:=orm.NewOrm()
	_,err=o.Insert(&ap)
	if err!=nil{
		return err
	}
	return nil
}

func AppMsgUpload(account string,app App) (error) {

	//根据url获取当前app消息的id
	//id:=GetIdByUrl(url)
	o:=orm.NewOrm()
	ap:=App{Id:app.Id}
	if o.Read(&ap)==nil{

		//获取app信息
		//apk, err := ipapk.NewAppParser(findAppById(app.Id).Url)
		//if err!=nil{
		//	return err
		//}
		//app信息入库
		app.Types=common.StrDelTrim(app.Types)
		//app.Root可以为空，为空表示仅自己可见
		//ap.Name=apk.Name
		ap.Types=app.Types
		ap.Company=getCompany(account)
		ap.Root=","+app.Root+","
		ap.Status=getStatu(app.Status)
		ap.Describe=app.Describe
		//ap.Picture=app.Picture
		//版本判断问题
		//if checkVersion(apk.Version,apk.Name)==false{
		//	return errors.New("version false")
		//}
		//ap.Version=apk.Version
		//ap.Icon=app.Icon
		ap.Newfeatures=app.Newfeatures
		ap.Priority=1
		ap.Url=findAppById(app.Id).Url
		o:=orm.NewOrm()
		_,err:=o.Update(&ap)
		if err!=nil{
			return err
		}
		return nil
	}else {
		return errors.New("don't exist")
	}

}


func AppMsgShowSuperAdmin(status string,typ string,company string) ([]App,error) {
	//rol:=findRole(account)
	//if rol==4{
	//	return nil,errors.New("have no access")
	//}
	//if rol==2||rol==3{
	//	company=getCompany(account)
	//}
	o := orm.NewOrm()
	var c []App
	com := new(App)
	qs := o.QueryTable(com)
	if status!=""{
		qs=qs.Filter("status",status)
	}
	if typ!=""{
		qs=qs.Filter("types",typ)
	}
	if company!=""{
		qs=qs.Filter("company",company)
	}
	_, err := qs.All(&c)
	return c, err
}

func AppMsgEditAdmin(account string,a App)  error{
	rol:=findRole(account)
	if rol!=2&&rol!=3{
		return errors.New("have no access")
	}
	o:=orm.NewOrm()
	app:=App{Id:a.Id}
	if o.Read(&app)==nil{
		//判断该app是否属于该公司
		accountcompany:=getCompany(account)
		appcompany:=AppShowById(a.Id).Company
		if accountcompany!=appcompany{
			return errors.New("not yours,have no access")
		}
		a.Types=common.StrDelTrim(a.Types)
		a.Root=common.StrDelTrim(a.Root)
		a.Describe=common.StrDelTrim(a.Describe)
		//a.Picture=common.StrDelTrim(a.Picture)
		a.Newfeatures=common.StrDelTrim(a.Newfeatures)
		a.Status=common.StrDelTrim(a.Status)
		if a.Types==""||a.Status==""{
			return errors.New("can't be null")
		}
		app.Types=a.Types
		app.Root=","+a.Root+","
		app.Describe=a.Describe
		//app.Picture=a.Picture
		app.Newfeatures=a.Newfeatures
		app.Status=a.Status
		_, err := o.Update(&app)
		return err
	}else {
		return errors.New("don't exist")
	}
	return nil
}

func AppUpdate(id int,url string) error {
	o:=orm.NewOrm()
	app:=App{Id:id}
	apk, err := ipapk.NewAppParser(findAppById(app.Id).Url)
	if err!=nil{
		return err
	}
	if o.Read(&app)==nil{
		app.Url=url
		app.Name=apk.Name
		app.Version=apk.Version
		_, err := o.Update(&app)
		return err
	}else {
		return errors.New("don't exist")
	}
	return nil
}

func AppMsgEditSuperAdmin(account string,a App) error {
	rol:=findRole(account)
	if rol!=1{
		return errors.New("have no access")
	}
	o:=orm.NewOrm()
	app:=App{Id:a.Id}
	if o.Read(&app)==nil{
		a.Types=common.StrDelTrim(a.Types)
		a.Root=common.StrDelTrim(a.Root)
		a.Describe=common.StrDelTrim(a.Describe)
	//	a.Picture=common.StrDelTrim(a.Picture)
		a.Newfeatures=common.StrDelTrim(a.Newfeatures)
		a.Status=common.StrDelTrim(a.Status)
		if a.Types==""||a.Status==""{
			return errors.New("can't be null")
		}
		app.Types=a.Types
		app.Root=a.Root
		app.Describe=a.Describe
		//app.Picture=a.Picture
		app.Newfeatures=a.Newfeatures
		app.Status=a.Status
		app.Priority=a.Priority
		_, err := o.Update(&app)
		return err
	}else {
		return errors.New("don't exist")
	}
	return nil
}

func AppShowById(id int)App  {
	o:=orm.NewOrm()
	com:=App{Id:id}
	o.Read(&com,"id")
	return com
}

//将文件名称改为唯一文件名
func PicUpload(name string)  (string,error){
	nm:=strings.Split(name,".")
	if len(nm)<2{
		return "",errors.New("file error")
	}
	tail:=nm[len(nm)-1]
	if tail!="jpg"&&tail!="ico"&&tail!="png"&&tail!="apk"&&tail!="ipa"{
		return "",errors.New("type error")
	}
	//改名,使其唯一
	ud:=uuid.Must(uuid.NewV4(),nil)
	u:=fmt.Sprint(ud)+"."+tail
	return u,nil
}

func Pngencode(id int,url string)  error{
	u:=findAppById(id).Url
	if u==""{return errors.New("don't exist")}
	apk,err:=ipapk.NewAppParser(u)
	if err!=nil{
		return err
	}
	file,err:=os.Create(url)
	defer file.Close()
	if err!=nil{
		return err
	}
	return png.Encode(file,apk.Icon)
}

func pathIsOk(path string) (bool,error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}
func PathCreate(path string)error  {
	ok,err:=pathIsOk(path)
	if err!=nil{return err}
	if ok==false{
		err=os.Mkdir(path,os.ModePerm)
	}
	return err
}
func PicUpdate(id int,pic string) error {
	o := orm.NewOrm()
	var c []App
	com := new(App)
	qs := o.QueryTable(com)
	_, err := qs.Filter("id", id).All(&c)
	if err!=nil{
		return err
	}else {
		if len(c)==0{return errors.New("don't exist")}
		o:=orm.NewOrm()
		app:=App{Id:c[0].Id}
		if o.Read(&app)==nil{
			app.Picture=c[0].Picture+","+pic
			_, err := o.Update(&app)
			return err
		}else {
			return errors.New("don't exist")
		}
	}
}

func PicDel(id int) error {
	o := orm.NewOrm()
	var c []App
	com := new(App)
	qs := o.QueryTable(com)
	_, err := qs.Filter("id", id).All(&c)
	if err!=nil{
		return err
	}else {
		if len(c)==0{return errors.New("don't exist")}
		o:=orm.NewOrm()
		app:=App{Id:c[0].Id}
		if o.Read(&app)==nil{
			app.Picture=""
			_, err := o.Update(&app)
			return err
		}else {
			return errors.New("don't exist")
		}
	}
}
func DownUpdate(id int,down string) error {
	o := orm.NewOrm()
	var c []App
	com := new(App)
	qs := o.QueryTable(com)
	_, err := qs.Filter("id", id).All(&c)
	if err!=nil{
		return err
	}else {
		if len(c)==0{return errors.New("don't exist")}
		o:=orm.NewOrm()
		app:=App{Id:c[0].Id}
		if o.Read(&app)==nil{
			app.Download=down
			_, err := o.Update(&app)
			return err
		}else {
			return errors.New("don't exist")
		}
	}
}
func IconUpdate(id int,pic string) error {
	o := orm.NewOrm()
	var c []App
	com := new(App)
	qs := o.QueryTable(com)
	_, err := qs.Filter("id", id).All(&c)
	if err!=nil{
		return err
	}else {
		if len(c)==0{return errors.New("don't exist")}
		o:=orm.NewOrm()
		app:=App{Id:c[0].Id}
		if o.Read(&app)==nil{
			app.Icon=pic
			_, err := o.Update(&app)
			return err
		}else {
			return errors.New("don't exist")
		}
	}
}
//上传app到fir，需要返回下载地址
func AppUpload(id int) (error) {
	//通过id获得file路径
	file:=findAppById(id).Url
	if file==""{return errors.New("dont exist")}
	for{
		//上传app
		up:=exec.Command("fir","publish",file,"-T",apitoken)
		//up.Stdout=os.Stdout
		if err:=up.Run();err!=nil{
			return err
		}
		break
		return nil
	}
	return nil
}
//时间到了之后，需要改变数据status的状态
func ChangeStatus(file string,t string,f chan int) error {
	apk, err := ipapk.NewAppParser(file)
	if err!=nil{
		return err
	}
	timeTicker := time.NewTicker(time.Minute*59)
	for{
		if checkTime(t)==false{
			//执行上线操作
			//获取最新状态的app信息
			app:=getLatestStatus(apk.Name)
			//将状态改成已上线
			change(app.Id)
			break
		}
		<-timeTicker.C
	}
	f<-1
	// 清理计时器
	timeTicker.Stop()
	return nil
}
//func checkVersion(version string,name string) bool {
//	old:=getVersion(name)
//	if old=="0"{return true}
//	olds:=strings.Split(old,".")
//	news:=strings.Split(version,".")
//	if len(olds)!=3||len(news)!=3{
//		return false
//	}
//	o0,_:=strconv.Atoi(olds[0])
//	n0,_:=strconv.Atoi(news[0])
//	if n0<o0{return false}
//	if n0>o0{return true}
//	o1,_:=strconv.Atoi(olds[1])
//	n1,_:=strconv.Atoi(news[1])
//	if n1>o1{return true}
//	if n1<o1{return false}
//	o2,_:=strconv.Atoi(olds[2])
//	n2,_:=strconv.Atoi(news[2])
//	if n2>o2{return true}
//	if n2<o2{return false}
//	return  false
//}

//获取app的总数
func getAppNum() int {
	o:=orm.NewOrm()
	var c []App
	com:=new(App)
	qs:=o.QueryTable(com)
	_,_=qs.All(&c)
	i:=len(c)
	return i
}

func getLatestStatus(appname string)App  {
	o:=orm.NewOrm()
	var c []App
	com:=new(App)
	qs:=o.QueryTable(com)
	_,_=qs.Filter("name",appname).All(&c)
	i:=len(c)
	if i==0{
		return *com
	}
	return c[i-1]
}
func getVersion(appname string) string {
	o:=orm.NewOrm()
	var c []App
	com:=new(App)
	qs:=o.QueryTable(com)
	_,_=qs.Filter("name",appname).All(&c,"version")
	i:=len(c)
	if i==0{
		return "0"
	}
	return c[i-1].Version
}

func findAppById(id int)App  {
	o:=orm.NewOrm()
	com:=App{Id:id}
	_=o.Read(&com,"id")
	return com
}

func GetIdByUrl(url string) int {

	o:=orm.NewOrm()
	com:=App{Url:url}
	_=o.Read(&com,"url")
	return com.Id
	//var c []App
	//com:=new(App)
	//qs:=o.QueryTable(com)
	//fmt.Println("uuuuuuuuuuuuuuuuu",url)
	//_,_=qs.Filter("url",url).All(&c,"id")
	//fmt.Println("ddddddddddddddddd",c)
	//i:=len(c)
	//if i==0{
	//	return 0
	//}
	//return c[i-1].Id
}

func change(id int)  {
	o := orm.NewOrm()
	user := App{Id:id}
	if o.Read(&user) == nil {
		user.Status=status1
		o.Update(&user)
	}
}

func getStatu(time string) string {
	//app.Time可以为空，为空表示立即上线,不为空返回数据为X小时或X天
	status:=""
	if common.StrDelTrim(time)==""{
		status=status1
	}else {
		status=status2
	}
	return status
}
//获取可见企业列表，需要提供api
func GetRoot(account string) []User {
	if findRole(account)==4{
		return nil
	}
	//根据账号获取公司
	co:=getCompany(account)
	//根据公司获取所有该公司的用户
	o := orm.NewOrm()
	var c []User
	com := new(User)
	qs := o.QueryTable(com)
	qs.Filter("company__exact", co).All(&c)
	return c
}
var t1=time.Now()
func checkTime(tim string) bool {
	tt,_:=time.ParseDuration(tim+"h")
	tafter:=t1.Add(tt)
	bo:=tafter.After(time.Now())
	return  bo
}
//-----------------
func GetDownload(name string,version string)  string{
	client:=&http.Client{}
	url:="http://api.bq04.com/apps?api_token="+apitoken
	//jsonStr, _ := json.Marshal(p)
	resp, err := client.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	result, _ := ioutil.ReadAll(resp.Body)

	stu:=&msg{}
	err=json.Unmarshal(result,&stu)
	if err!=nil{
		fmt.Println(err)
	}
	fmt.Println(stu.Apps_count)
	for i:=0;i<stu.Apps_count;i++{
		if	stu.Items[i].Name==name&&stu.Items[i].Master_release.Version==version{
			s:=fmt.Sprint("http://",stu.Items[i].Download_domain,"/",stu.Items[i].Short)
			return s
		}
	}
	return ""
}

type msg struct {
	Apps_count int
	Page_size int
	Items []m
}
type m struct {
	Id string
	User_id string
	Org_id string
	Type string
	Name string
	Short string
	Bundle_id string
	Genre_id int
	Is_opened bool
	Download_domain string
	Download_domain_https_ready bool
	Web_template string
	Custom_market_url string
	Has_combo bool
	Created_at int
	Updated_at int
	Expired_at int
	Stale_at int
	Icon_url string
	Master_release v
}
type v struct {
	Version string
	Build string
	Release_type string
	Distribution_name string
	Supported_platform string
	Created_at int
}